# script to generate layout.yaml, which is used by a kicad plugin to set component positions, etc.
# plugin: https://github.com/mcbridejc/kicad_component_layout
#
# see pcb/README.md for more info

import math
from math import degrees, radians
import yaml
import sys
import os

# add parent dir to path so we can import oasis_constants
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
from oasis_constants import (
    ledboard_inner_r,
    ledboard_outer_r,
    led_count,
    led0_angle_deg,
    hole0_angle_deg,
)

# COORDINATE SYSTEM NOTES
#
# The center of the board in KiCad is at (100, 100) as recorded in the `ORIGIN`
# variable below. All positions in the `components` mapping are *relative* to
# this origin. For example a component placed at (0, 0), will show up at
# (100, 100) in absolute coordinates in KiCad.
#
# Angles in `components` are in degrees and are clockwise from the +x axis.
# WARNING: this differs from the constants in oasis_constants, which are
# defined counter-clockwise from the +x axis.
#
ORIGIN = [100, 100]

# `components` contains an entry for each item that we would like to place
# programmatically. The code in this file adds entries to the mapping, then at
# the very end, writes `components` to a yaml file for import into kicad via
# the layout plugin.
components = {}

ledboard_center_r = (ledboard_inner_r + ledboard_outer_r) / 2.0


# angle is in radians
def pos_at_angle_and_radius(angle, radius):
    x = round(radius * math.cos(angle), 3)
    y = round(radius * math.sin(angle), 3)
    rotation = degrees(-angle) + 90
    return (x, y, rotation)


# leds evenly-spaced on the bottom of the board
for i in range(led_count):
    ref = "D%d" % (i + 1)

    angle_between_leds = 2 * math.pi / led_count
    # position D1 closest to the led driver
    theta = i * angle_between_leds + radians(-led0_angle_deg)

    p = pos_at_angle_and_radius(theta, ledboard_center_r)

    components[ref] = {
        "location": p[0:2],
        "rotation": p[2],
        "theta": degrees(theta),
        # 'flip': True,  # place on bottom
        # 'flip': False,
    }

# board mounting holes
num_holes = led_count
for i in range(num_holes):
    ref = "H%d" % (i + 1)

    angle_between_holes = 2 * math.pi / led_count
    theta = i * angle_between_leds + radians(-hole0_angle_deg)

    p = pos_at_angle_and_radius(theta, ledboard_center_r)

    components[ref] = {
        "location": p[0:2],
        "rotation": 0,
        "theta": degrees(theta),
    }

# # LED driver placement
# ldd_angle = radians(-led_driver_angle_deg)
# ldd_pos = pos_at_angle_and_radius(ldd_angle, ledboard_center_r)
# components['PS1'] = {
#     'location': ldd_pos[0:2],
#     'rotation': ldd_pos[2] + 90,
# }

j1_ang = (components["D1"]["theta"] + components["H5"]["theta"] + 360) / 2
j1_pos = pos_at_angle_and_radius(radians(j1_ang), ledboard_center_r)
components["J1"] = {
    "location": j1_pos[0:2],
    "rotation": j1_pos[2],
}

layout = {
    "origin": ORIGIN,
    "components": components,
}

with open("layout.yaml", "w") as f:
    f.write("# DO NOT EDIT - this file was autogenerated by layout.py\n")
    f.write(yaml.safe_dump(layout, default_flow_style=None))
